/***
* ==++==
*
* Copyright (c) Microsoft Corporation.  All rights reserved.
*
* ==--==
* =+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
*
* actor_serialization.h
*
* Serialization for actor specific types
*
* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
****/
#pragma once

#include "actor_public.h"
#include "serialization.h"

namespace actors
{
    class PID;
    class actor;
    class _actor_info;
    typedef std::shared_ptr<_actor_info> actor_info;

    /// <summary>
    /// Serializer used to deserialize (read) from a linked list of messages.
    /// </summary>
    class msg_list_serializer : public Serializer
    {
    public:
        _DISPIMP msg_list_serializer(dispatch_msg *head);

        /// <summary>
        /// read a number of bytes from the underlying array and 
        /// advance the internal read position.
        /// </summary>
        /// <param name="byteCount">The number of bytes to read</param>
        /// <param name="source">The address of the data block to copy to</param>
        _DISPIMP virtual bool read(size_t byteCount, void *dest);

    private:
        __int64 m_blockLength;
        size_t m_blockOffset;
        block_header *m_first;
        block_header *m_current;
    };

} // namespace actors

#pragma region "Non-generic serializers"

_DISPIMP size_t calculate_size(const actors::PID pid);
_DISPIMP size_t calculate_size(const actors::actor *proc);

_DISPIMP bool serialize(const actors::PID pid, actors::Serializer &serializer);
_DISPIMP bool serialize(const actors::actor *proc, actors::Serializer &serializer);

_DISPIMP bool deserialize(actors::PID &pid, actors::Serializer &serializer);
_DISPIMP bool deserialize(actors::actor *proc, actors::Serializer &serializer);
_DISPIMP bool deserialize(actors::actor_info info, actors::Serializer &serializer);

_DISPIMP size_t calculate_size(const actors::general_msg &msg);
_DISPIMP bool serialize(const actors::general_msg &msg, actors::Serializer &serializer);
_DISPIMP bool deserialize(actors::general_msg &msg, actors::Serializer &serializer);

_DISPIMP size_t calculate_size(actors::block_header *msg);
_DISPIMP bool serialize(actors::block_header *msg, actors::Serializer &serializer);
_DISPIMP bool deserialize(actors::block_header *&msg, actors::Serializer &serializer);

_DISPIMP size_t calculate_size(actors::general_msg *msg);
_DISPIMP bool serialize(actors::general_msg *msg, actors::Serializer &serializer);

_DISPIMP size_t calculate_size(const actors::general_msg *msg);
_DISPIMP bool serialize(const actors::general_msg *msg, actors::Serializer &serializer);
_DISPIMP bool deserialize(actors::general_msg *&msg, actors::Serializer &serializer);

_DISPIMP size_t calculate_size(const actors::remote_msg &msg);
_DISPIMP bool serialize(const actors::remote_msg &msg, actors::Serializer &serializer);
_DISPIMP bool deserialize(actors::remote_msg &msg, actors::Serializer &serializer);
#pragma endregion
